const fs = require('fs');
const path = require('path');
const sharp = require('sharp');

// 需要处理的目录
const IMAGE_DIRS = [
  'miniprogram/images/discovers/png',
  'miniprogram/images/recipes',
  'miniprogram/images/tabbar',
  'miniprogram/images/icons',
  'miniprogram/images/meals'
];

// 图片设置
const MAX_SIZE_KB = 150; // 最大允许大小，单位KB
const MAX_DIMENSION = 300; // 最大图片尺寸

// 收集统计数据
const stats = {
  processed: 0,
  skipped: 0,
  failed: 0,
  totalSaved: 0,
  largeImages: []
};

// 处理图片
async function processImage(filePath) {
  try {
    console.log(`处理图片: ${filePath}`);
    
    // 获取文件信息
    const fileStats = fs.statSync(filePath);
    const originalSizeKB = fileStats.size / 1024;
    
    // 记录大图片
    if (originalSizeKB > 500) {
      stats.largeImages.push({
        path: filePath,
        size: originalSizeKB.toFixed(2) + 'KB'
      });
    }
    
    // 跳过已经足够小的图片
    if (originalSizeKB <= MAX_SIZE_KB) {
      console.log(`  跳过 - 已经小于 ${MAX_SIZE_KB}KB: ${originalSizeKB.toFixed(2)}KB`);
      stats.skipped++;
      return;
    }
    
    // 获取文件信息
    const ext = path.extname(filePath).toLowerCase();
    const filename = path.basename(filePath, ext);
    const dirname = path.dirname(filePath);
    const tempPath = path.join(dirname, `${filename}_temp${ext}`);
    
    // 读取图片信息
    const metadata = await sharp(filePath).metadata();
    console.log(`  原始尺寸: ${metadata.width}x${metadata.height}, 大小: ${originalSizeKB.toFixed(2)}KB`);
    
    // 计算新尺寸，保持宽高比
    let width = metadata.width;
    let height = metadata.height;
    
    let resizeNeeded = false;
    if (width > MAX_DIMENSION || height > MAX_DIMENSION) {
      resizeNeeded = true;
      if (width > height) {
        height = Math.round((height / width) * MAX_DIMENSION);
        width = MAX_DIMENSION;
      } else {
        width = Math.round((width / height) * MAX_DIMENSION);
        height = MAX_DIMENSION;
      }
      console.log(`  调整尺寸至: ${width}x${height}`);
    }
    
    // 处理不同格式
    let sharpInstance = sharp(filePath);
    
    if (resizeNeeded) {
      sharpInstance = sharpInstance.resize(width, height);
    }
    
    if (ext === '.png') {
      await sharpInstance.png({ quality: 60, compressionLevel: 9 }).toFile(tempPath);
    } else if (ext === '.jpg' || ext === '.jpeg') {
      await sharpInstance.jpeg({ quality: 60 }).toFile(tempPath);
    } else {
      console.log(`  跳过 - 不支持的格式: ${ext}`);
      stats.skipped++;
      return;
    }
    
    // 检查新文件大小
    const newStats = fs.statSync(tempPath);
    const newSizeKB = newStats.size / 1024;
    
    // 如果新文件更小，则替换原文件
    if (newSizeKB < originalSizeKB) {
      fs.unlinkSync(filePath);
      fs.renameSync(tempPath, filePath);
      
      const reduction = originalSizeKB - newSizeKB;
      const reductionPercent = (reduction / originalSizeKB) * 100;
      
      console.log(`  压缩成功: ${originalSizeKB.toFixed(2)}KB → ${newSizeKB.toFixed(2)}KB (减少 ${reductionPercent.toFixed(2)}%)`);
      
      stats.processed++;
      stats.totalSaved += reduction;
    } else {
      fs.unlinkSync(tempPath);
      console.log(`  压缩失败: 新文件更大 (${newSizeKB.toFixed(2)}KB > ${originalSizeKB.toFixed(2)}KB)`);
      stats.failed++;
    }
  } catch (error) {
    console.error(`处理图片失败: ${filePath}`, error);
    stats.failed++;
  }
}

// 递归处理目录
async function processDirectory(directory) {
  console.log(`\n扫描目录: ${directory}`);
  
  try {
    // 检查目录是否存在
    if (!fs.existsSync(directory)) {
      console.log(`  目录不存在: ${directory}`);
      return;
    }
    
    // 读取目录内容
    const items = fs.readdirSync(directory);
    console.log(`  发现 ${items.length} 个文件/目录`);
    
    let imageCount = 0;
    
    // 处理每个文件
    for (const item of items) {
      const itemPath = path.join(directory, item);
      
      try {
        const fileStats = fs.statSync(itemPath);
        
        if (fileStats.isDirectory()) {
          // 递归处理子目录
          await processDirectory(itemPath);
        } else if (fileStats.isFile() && /\.(png|jpg|jpeg)$/i.test(item)) {
          // 处理图片文件
          imageCount++;
          await processImage(itemPath);
        }
      } catch (err) {
        console.error(`无法访问: ${itemPath}`, err);
      }
    }
    
    console.log(`  目录中发现 ${imageCount} 个图片文件`);
  } catch (error) {
    console.error(`处理目录失败: ${directory}`, error);
  }
}

// 主函数
async function main() {
  console.log('===== 开始优化图片 =====');
  console.log(`最大允许大小: ${MAX_SIZE_KB}KB, 最大尺寸: ${MAX_DIMENSION}px`);
  
  const startTime = Date.now();
  let processedDirs = 0;
  
  for (const dir of IMAGE_DIRS) {
    if (fs.existsSync(dir)) {
      await processDirectory(dir);
      processedDirs++;
    } else {
      console.log(`目录不存在: ${dir}`);
    }
  }
  
  const endTime = Date.now();
  const duration = (endTime - startTime) / 1000;
  
  console.log('\n===== 图片优化完成 =====');
  console.log(`处理耗时: ${duration.toFixed(2)}秒`);
  console.log(`处理目录数: ${processedDirs}`);
  console.log(`处理成功: ${stats.processed} 张图片`);
  console.log(`已跳过: ${stats.skipped} 张图片`);
  console.log(`处理失败: ${stats.failed} 张图片`);
  console.log(`总共节省: ${stats.totalSaved.toFixed(2)}KB (${(stats.totalSaved/1024).toFixed(2)}MB)`);
  
  if (stats.largeImages.length > 0) {
    console.log('\n超过500KB的大图片:');
    stats.largeImages.forEach((img, i) => {
      console.log(`${i+1}. ${img.path} (${img.size})`);
    });
  }
}

// 运行程序
main().catch(err => {
  console.error('程序执行出错:', err);
}); 